package cz.none.bezbarier.web.controller;

import java.util.Locale;

import javax.validation.Valid;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import cz.none.bezbarier.web.form.FiltreForm;
import cz.none.bezbarier.web.form.PlaceForm;
import cz.none.bezbarier.web.model.Place;
import cz.none.bezbarier.web.model.Type;
import cz.none.bezbarier.web.service.PlaceService;
import cz.none.bezbarier.web.service.exception.ServiceException;
import cz.none.bezbarier.web.util.Constants;
import cz.none.bezbarier.web.util.PNPageImpl;
import cz.none.bezbarier.web.vo.FlashMessage.Severity;

@Controller
@RequestMapping(Constants.Page.CATALOG_M)
public class CatalogController extends AController {

	private static final Logger LOG = LoggerFactory.getLogger(CatalogController.class);

	@Autowired
	private PlaceService service;

	@RequestMapping(method = RequestMethod.GET)
	public String browseCatalogFirstPage(Model model, @ModelAttribute("form") @Valid FiltreForm form) {
		return prepareCatalog(1, model, form);
	}

	@RequestMapping(value = "/{pageNumber}", method = RequestMethod.GET)
	public String browseCatalog(@PathVariable(value = "pageNumber") Integer pageNumber, Model model,
			@ModelAttribute("form") @Valid FiltreForm form) {

		return prepareCatalog(pageNumber, model, form);
	}

	@RequestMapping(Constants.Page.CATALOG_PLACE_M)
	public String showPlace(@PathVariable String placeId, Model model, RedirectAttributes redir) {

		try {
			model.addAttribute("place", service.find(placeId));
		} catch (ServiceException e) {
			addFlashMessage(redir, Severity.ERROR, "catalog.edit.error.bad.id", placeId);
			setActiveMenu(redir, Constants.Menu.CATALOG);
			return redirectToPage(Constants.Page.CATALOG_M);
		}

		return Constants.Page.CATALOG_SHOW;
	}

	@PreAuthorize("hasRole('AUTHORIZED')")
	@RequestMapping(Constants.Page.CATALOG_EDIT_M)
	public String addPlace(Model model,
			@RequestHeader(value = "referer", required = false) final String referer) {
		PlaceForm f = new PlaceForm();

		return fillModelAndDisplayForm(referer, f, model);
	}

	@PreAuthorize("hasRole('AUTHORIZED')")
	@RequestMapping(Constants.Page.CATALOG_EDIT_EXIST_M)
	public String editPlace(@PathVariable String placeId, Model model,
			@RequestHeader(value = "referer", required = false) final String referer, RedirectAttributes redir) {

		PlaceForm f = null;
		try {
			f = service.fillForm(placeId);
		} catch (ServiceException e) {
			addFlashMessage(redir, Severity.ERROR, "catalog.edit.error.bad.id", placeId);
			setActiveMenu(redir, Constants.Menu.CATALOG);
			return redirectToPage(Constants.Page.CATALOG_M);
		}

		return fillModelAndDisplayForm(referer, f, model);
	}

	@PreAuthorize("hasRole('AUTHORIZED')")
	@RequestMapping(value = Constants.Page.CATALOG_EDIT_M, method = RequestMethod.POST)
	public String savePlace(@ModelAttribute @Valid PlaceForm form, BindingResult result,
			Locale locale, Model model, @RequestParam("_submit") final String action) {

		if (!Constants.Form.SUBMIT.equals(action)) {
			LOG.debug("savePlace():: clicked storno");
			return redirectToReferer(form);
		}

		if (result.hasErrors()) {
			LOG.debug("savePlace():: form has errors");
			model.addAttribute("allTypes", Type.values());
			addFlashMessage(model, result, locale);
			return Constants.Page.CATALOG_FORM;
		}

		service.saveForm(form);

		return redirectToReferer(form);
	}

	private String prepareCatalog(Integer pageNumber, Model model, FiltreForm form) {
		setActiveMenu(model, Constants.Menu.CATALOG);

		if (pageNumber == null) {
			pageNumber = 1;
		} else if (pageNumber < 1) {
			pageNumber = 1;
		}

		model.addAttribute("page", new PNPageImpl<Place>(service.getPlaces(pageNumber, form),
				Constants.Common.PAGINATOR_SIZE));

		model.addAttribute("form", form);
		model.addAttribute("allTypes", Type.values());
		if (null != form.getType() || (null != form.getName() && !"".equals(form.getName()))) {
			model.addAttribute("filtred", true);
		}

		return Constants.Page.CATALOG_BROWSE;
	}

	private String fillModelAndDisplayForm(String referer, PlaceForm form, Model model) {
		setActiveMenu(model, Constants.Menu.CATALOG);

		form.setReferer(referer);
		model.addAttribute("form", form);
		model.addAttribute("allTypes", Type.values());

		return Constants.Page.CATALOG_FORM;
	}

}
